package com.xuecheng.media.service.impl;

import com.alibaba.druid.sql.visitor.functions.If;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.vod.model.v20170321.GetPlayInfoResponse;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xuecheng.api.content.media.model.dto.MediaDTO;
import com.xuecheng.api.content.media.model.qo.QueryMediaModel;
import com.xuecheng.common.domain.code.CommonErrorCode;
import com.xuecheng.common.domain.page.PageRequestParams;
import com.xuecheng.common.domain.page.PageVO;
import com.xuecheng.common.domain.response.RestResponse;
import com.xuecheng.common.enums.common.AuditEnum;
import com.xuecheng.common.enums.common.ResourceTypeEnum;
import com.xuecheng.common.exception.ExceptionCast;
import com.xuecheng.common.util.StringUtil;

import com.xuecheng.media.common.constant.MediaErrorCode;
import com.xuecheng.media.common.utils.AliyunVODUtil;
import com.xuecheng.media.convert.MediaConvert;
import com.xuecheng.media.entity.Media;
import com.xuecheng.media.mapper.MediaMapper;
import com.xuecheng.media.service.MediaService;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * <p>
 * 媒资信息 服务实现类
 * </p>
 *
 * @author itcast
 */
@Slf4j
@Service
public class MediaServiceImpl extends ServiceImpl<MediaMapper, Media> implements MediaService {


    @Override
    public PageVO queryMediaList(PageRequestParams params, QueryMediaModel model, Long companyId) {

        // 2.判断关键数据（代码健壮性）
        //      关键数据：数据来源是前端
        //          分页数据需要判断：pageNo、pageSize
        if (params.getPageNo() < 1) {
            params.setPageNo(PageRequestParams.DEFAULT_PAGE_NUM);
        }

        if (params.getPageSize() < 1) {
            params.setPageSize(PageRequestParams.DEFAULT_PAGE_SIZE);
        }
        //  3.构建Page（MP）对象
        Page<Media> page = new Page<>(params.getPageNo(), params.getPageSize());
        //  4.构建查询构建对象
        LambdaQueryWrapper<Media> queryWrapper = new LambdaQueryWrapper<>();
        // select * from course_base where name like ? and audit_status = ?
        // 完整版
        // // 课程名称(模糊匹配)
        // if (StringUtil.isNotBlank(model.getCourseName())) {
        //     queryWrapper.like(CourseBase::getName, model.getCourseName());
        // }
        // // 课程审核状态（精确匹配）
        // if (StringUtil.isNotBlank(model.getAuditStatus())) {
        //     queryWrapper.eq(CourseBase::getAuditStatus, model.getAuditStatus());
        // }
        // 简化版
        queryWrapper.like(StringUtil.isNotBlank(model.getFilename()),Media::getFilename, model.getFilename());
        queryWrapper.eq(StringUtil.isNotBlank(model.getAuditStatus()),Media::getAuditStatus, model.getAuditStatus());
        queryWrapper.eq(Media::getCompanyId, companyId);
        // 按照时间倒序--最新创建出的数据会在最上面
        queryWrapper.orderByDesc(Media::getCreateDate);
        //  5.查询数据
        //      分页对象Page
        //      查询构建对象
        Page<Media> pageResult = this.page(page, queryWrapper);
        List<Media> records = pageResult.getRecords();
        long total = pageResult.getTotal();
        List<MediaDTO> dtos = Collections.EMPTY_LIST;
        if (!(CollectionUtils.isEmpty(records))) {
            dtos = new ArrayList<>();
            dtos = MediaConvert.INSTANCE.entitys2dtos(records);
        }
        //  6.将查询结果封装并返回-->PageVO
        PageVO pageVO = new PageVO<>(dtos, total, params.getPageNo(), params.getPageSize());
        return pageVO;
    }
    /*
     * 业务分析：
     *   0.是否开启事务
     *   1.判断关键
     *       companyid  filename  fileid(videoId)
     *   2.给信息数据赋值默认值
     *       auditStatus：未审核
     *       视频的播放地址
                在开发阶段无需值
                    现在无域名，无法设置cdn
                    播放地址默认为3600秒
                生产环境阶段需要赋值
                    在有域名，可以设置cdn域名
                    播放地址可以时效无限期
     *   3.保存信息
     *   4.将数据库最新数据返回
     * */
    @Transactional
    public MediaDTO createMedia(MediaDTO dto) {
        //1.判断关键
        //     companyid  filename  fileid(videoId)
        if (ObjectUtils.isEmpty(dto.getCompanyId())||
                StringUtil.isBlank(dto.getFilename())||
                StringUtil.isBlank(dto.getFileId())
        ) {
            ExceptionCast.cast(CommonErrorCode.E_100101);
        }
        // 2.给信息数据赋值默认值
        //     auditStatus：未审核
        dto.setAuditStatus(AuditEnum.AUDIT_UNPAST_STATUS.getCode());
        // 3.保存信息
        Media media = MediaConvert.INSTANCE.dto2entity(dto);
        boolean result = this.save(media);
        if (!result) {
            ExceptionCast.cast(MediaErrorCode.E_140001);
        }
        // 4.将数据库最新数据返回
        Media po = this.getById(media.getId());
        MediaDTO resultDTO = MediaConvert.INSTANCE.entity2dto(po);
        return resultDTO;
    }

    @Override
    public String getPlayUrlMediaId(Long mediaId, Long companyId) {



                // 1.判断关键数据
                if (ObjectUtils.isEmpty(mediaId)||
                        ObjectUtils.isEmpty(companyId)
                ) {
                    ExceptionCast.cast(CommonErrorCode.E_100101);
                }

                // 2.判断业务数据
                // 媒资信息是否存在
                LambdaQueryWrapper<Media> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(Media::getId, mediaId);

                if (!(ObjectUtils.nullSafeEquals(companyId, -1))) {
                    queryWrapper.eq(Media::getCompanyId, companyId);
                }

                Media media = this.getOne(queryWrapper);

                if (ObjectUtils.isEmpty(media)) {
                    ExceptionCast.cast(MediaErrorCode.E_140005);
                }

                // 3.获得媒资文件的资源路径地址
                // 判断媒资类型是否是视频类型，如果是需要获得aliyun视频的地址
                String type = media.getType();


                String resourceUrl = null;

                if (ResourceTypeEnum.VIDEO. getCode().equals(type)) {
                    resourceUrl = getAliyunVodPlayUrl(media.getFileId());
                } else if (ResourceTypeEnum.DOCUMENT.getCode().equals(type)){
                    //获得的媒资文档的资源访问地址路径
                } else if (ResourceTypeEnum.WORK.getCode().equals(type)){
                    //获得的媒资文档的资源访问地址路径
                }


                return resourceUrl;
            }




    @Value("${aliyun.region}")
            private  String region;
            @Value("${aliyun.accessKeyId}")
            private  String accessKeyId;
            @Value("${aliyun.accessKeySecret}")
            private  String accessKeySecret;


            /**
             * 获得阿里云视频播放地址
             * @param fileId
             * @return
             */
            private String getAliyunVodPlayUrl(String fileId) {

                String playURL = null;
                try {
                    DefaultAcsClient client = AliyunVODUtil.initVodClient(region, accessKeyId, accessKeySecret);

                    GetPlayInfoResponse playInfo = AliyunVODUtil.getPlayInfo(client, fileId);

                    List<GetPlayInfoResponse.PlayInfo> playInfoList = playInfo.getPlayInfoList();

                    if (CollectionUtils.isEmpty(playInfoList)) {
                        ExceptionCast.cast(MediaErrorCode.E_140018);
                    }

                    // 默认获得第一个播放地址
                    playURL = playInfoList.get(0).getPlayURL();
                } catch (Exception e) {
                    log.error(MediaErrorCode.E_140012.getDesc()+" : {}",e.getMessage());
                    ExceptionCast.cast(MediaErrorCode.E_140012);
                }

                return playURL;
            }
    @Override
    public void removeMadiaById(Long mediaId, Long companyId) {
        //判断关键数据
        //传入id是否正确 为空
        if (ObjectUtils.isEmpty(mediaId) || ObjectUtils.isEmpty(companyId)) {
            ExceptionCast.cast(CommonErrorCode.E_100101);
        }

        LambdaUpdateWrapper<Media> UpdateWrapper = new LambdaUpdateWrapper<>();
        UpdateWrapper.eq(Media::getCompanyId, companyId);
        UpdateWrapper.eq(Media::getId, companyId);
        Media media = this.getOne(UpdateWrapper);
            }

    @Override
    public RestResponse<MediaDTO> getById4Service(Long mediaId) {
        //判断关键数据
        if (ObjectUtils.isEmpty(mediaId)) {


            return RestResponse.validfail(CommonErrorCode.E_100101);
        }
        //判断业务数据
        Media media = this.getById(mediaId);
        if (ObjectUtils.isEmpty(mediaId)) {
            return RestResponse.validfail(MediaErrorCode.E_140005);
        } else {
            MediaDTO mediaDTO = MediaConvert.INSTANCE.entity2dto(media);
            return RestResponse.success(mediaDTO);

        }


    }
}



